#include "redis_pool.hpp"
#include <cstring>
#include "../logger.hpp"

RedisPool::RedisPool(const RedisConfig& config)
    : ConnectionPool<redisContext>(config.pool_config)
    , config_(config) {}

std::shared_ptr<redisContext> RedisPool::create_connection() {
    struct timeval timeout = { 1, 500000 }; // 1.5 seconds
    auto* conn = redisConnectWithTimeout(
        config_.host.c_str(), 
        config_.port, 
        timeout
    );
    
    if (!conn || conn->err) {
        if (conn) {
            redisFree(conn);
        }
        return nullptr;
    }

    // 认证
    if (!config_.password.empty()) {
        auto* reply = (redisReply*)redisCommand(
            conn, 
            "AUTH %s", 
            config_.password.c_str()
        );
        if (reply) {
            freeReplyObject(reply);
        } else {
            redisFree(conn);
            return nullptr;
        }
    }

    // 选择数据库
    if (config_.database != 0) {
        auto* reply = (redisReply*)redisCommand(
            conn, 
            "SELECT %d", 
            config_.database
        );
        if (reply) {
            freeReplyObject(reply);
        } else {
            redisFree(conn);
            return nullptr;
        }
    }

    // 打印日志，创建了redis连接
    Logger::info("create redis connection");

    return std::shared_ptr<redisContext>(conn, [](redisContext* conn) {
        Logger::info("{} close redis connection", __func__);
    });
}

bool RedisPool::validate_connection(redisContext* conn) {
    if (!conn) return false;
    
    auto* reply = (redisReply*)redisCommand(conn, "PING");
    bool is_valid = false;
    
    if (reply) {
        is_valid = (reply->type == REDIS_REPLY_STRING && 
                   strcmp(reply->str, "PONG") == 0);
        freeReplyObject(reply);
    }
    
    return is_valid;
}

void RedisPool::close_connection(redisContext* conn) {
    if (conn) {
        redisFree(conn);
    }
}